#include <isr.h>
#include <io.h>
#include <defs.h>
#include <timer.h>
#include <vic.h>
#include <uart.h>
#include <terminal.h>
#include <syscalls.h>

void WakeAwaiters( sched *s, td *task, int eventid, int data ) {
  int i = s->waiters[eventid];
  if (i == -1) {
    return;
  }
  s->waiters[eventid] = -1;
  s->tasks[i].ret = data;
  s->tasks[i].state = STATE_READY;
  PqPushBack( &(s->queues[MAX_PRI]), &(s->tasks[i]) );
}

void TimerHandler( sched *s, td *task ) {
  timer *const timer3 = (timer*)( TIMER3_BASE );
  timer3->clear = 0;
  WakeAwaiters(s, task, EVENT_TIMER, SUCCESS);
}

void DefaultHandler( sched *s, td *task ) {
  SysPanic(s, task, "DefaultHandler", "Unknown interrupt triggered.");
}

void Uart1Handler( sched *s, td *task ) {
  uart *const uart1 = (uart*)( UART1_BASE );
  int int_flags = uart1->intl_d_int_clr;

  if (int_flags & MIS_MASK) {
    uart1->intl_d_int_clr = 0;
    WakeAwaiters(s, task, EVENT_UART1_TX, int_flags);
  } else {
    uart1->ctrl &= ~(RIEN_MASK | RTIEN_MASK);
    WakeAwaiters(s, task, EVENT_UART1_RX, int_flags);
  }
}

void Uart2Handler( sched *s, td *task ) { 
  uart *const uart2 = (uart*)( UART2_BASE );
  int int_flags = uart2->intl_d_int_clr;

  if (int_flags & TIS_MASK) {
    uart2->ctrl &= ~(TIEN_MASK);
    WakeAwaiters(s, task, EVENT_UART2_TX, int_flags);
  } else {
    uart2->ctrl &= ~(RIEN_MASK | RTIEN_MASK);
    WakeAwaiters(s, task, EVENT_UART2_RX, int_flags);
  }
}
